<template>
  <div class="day-input-wrapper">
    <el-input
      v-model="inputValue"
      :placeholder="placeholder"
      :size="size"
      :disabled="disabled"
      :class="{ 'is-error': hasError }"
      @input="handleInput"
      @blur="handleBlur"
      @focus="handleFocus"
    >
      <template #append>天</template>
    </el-input>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';

interface Props {
  modelValue?: string | number | null;
  placeholder?: string;
  size?: 'large' | 'default' | 'small';
  disabled?: boolean;
  min?: number;
  precision?: number;
  required?: boolean;
}

interface Emits {
  (e: 'update:modelValue', value: string | number | null): void;
  (e: 'change', value: string | number | null): void;
  (e: 'blur', event: FocusEvent): void;
  (e: 'focus', event: FocusEvent): void;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: null,
  placeholder: '请输入工天（大于0，保留两位小数）',
  size: 'default',
  disabled: false,
  min: 0,
  precision: 2,
  required: false
});

const emit = defineEmits<Emits>();

const inputValue = ref<string>('');
const hasError = ref(false);
const isFocused = ref(false);
const isInternalUpdate = ref(false); // 标记是否为内部更新

// 监听外部值变化
watch(
  () => props.modelValue,
  (newValue) => {
    // 如果是内部更新，不处理
    if (isInternalUpdate.value) {
      isInternalUpdate.value = false;
      return;
    }

    if (newValue !== null && newValue !== undefined && newValue !== '') {
      // 如果是数字类型，格式化为指定位数的小数
      if (typeof newValue === 'number') {
        inputValue.value = newValue.toFixed(props.precision);
      } else {
        // 如果是字符串，确保格式正确
        const numValue = parseFloat(String(newValue));
        if (!isNaN(numValue)) {
          inputValue.value = numValue.toFixed(props.precision);
        } else {
          inputValue.value = String(newValue);
        }
      }
    } else {
      inputValue.value = '';
    }
  },
  { immediate: true }
);

// 处理输入 - 输入时不进行格式化，允许用户自由输入
const handleInput = (value: string) => {
  if (!value) {
    inputValue.value = '';
    isInternalUpdate.value = true;
    emit('update:modelValue', null);
    return;
  }

  // 输入时只过滤掉非数字和小数点的字符，不进行格式化
  let formattedValue = value.replace(/[^\d.]/g, '');

  // 确保只有一个小数点
  const parts = formattedValue.split('.');
  if (parts.length > 2) {
    formattedValue = parts[0] + '.' + parts.slice(1).join('');
  }

  inputValue.value = formattedValue;
  isInternalUpdate.value = true;
  emit('update:modelValue', formattedValue || null);
  emit('change', formattedValue || null);
};

// 处理失焦 - 失焦时进行校验和格式化
const handleBlur = (event: FocusEvent) => {
  isFocused.value = false;

  if (inputValue.value) {
    // 失焦时进行格式化
    const numValue = parseFloat(inputValue.value);
    if (!isNaN(numValue)) {
      // 格式化为指定位数的小数
      const formattedValue = numValue.toFixed(props.precision);
      inputValue.value = formattedValue;
      isInternalUpdate.value = true;
      emit('update:modelValue', formattedValue);
      emit('change', formattedValue);
    }
  }

  validate();
  emit('blur', event);
};

// 处理聚焦
const handleFocus = (event: FocusEvent) => {
  isFocused.value = true;
  hasError.value = false;
  emit('focus', event);
};

// 验证
const validate = () => {
  if (props.required && (!inputValue.value || inputValue.value === '')) {
    hasError.value = true;
    return false;
  }

  if (inputValue.value) {
    const numValue = parseFloat(inputValue.value);
    if (isNaN(numValue) || numValue <= props.min) {
      hasError.value = true;
      return false;
    }
  }

  hasError.value = false;
  return true;
};

// 暴露验证方法
defineExpose({
  validate,
  clearError: () => {
    hasError.value = false;
  }
});
</script>

<style scoped>
.day-input-wrapper {
  width: 100%;
}

.day-input-wrapper :deep(.el-input__wrapper) {
  width: 100%;
}

.day-input-wrapper :deep(.el-input-group__append) {
  background-color: var(--el-fill-color-light);
  color: var(--el-text-color-regular);
  font-weight: 500;
}
</style>
